<?php

namespace controller\admin;

defined('IA_ROOT') || exit();

use mvc\Controller;
use facade\Model;
use facade\View;
use facade\Util;

class Account extends Controller
{
    // 基址
    protected $base_url;
    protected $site_url;

    // 语言
    protected $lang;

    // 初始化
    protected function initialize()
    {
        !session_id() && session_start();
        $this->lang = Util::lang();
        $this->site_url = "//{$_SERVER["SERVER_NAME"]}" . (isset($_SERVER["SERVER_PORT"]) ? (in_array($_SERVER["SERVER_PORT"], ["80", "443"]) ? "" : ":{$_SERVER['SERVER_PORT']}") : "");
        $this->base_url = "http" . ((isset($_SERVER["HTTPS"]) && in_array(strtolower($_SERVER["HTTPS"]), ["on", "1"])) || (isset($_SERVER["SERVER_PORT"]) && "443" == $_SERVER["SERVER_PORT"]) ? "s" : "") . ":{$this->site_url}";
        View::assign('lang', $this->lang);
        View::assign('site_url', $this->site_url);
        View::assign('localize', ['backend' => Util::tran('管理后台')]);
    }

    // 登录
    public function index()
    {
        $param = Util::param(['redirect_to']);
        $jump = isset($param['redirect_to']) && false === strpos($param['redirect_to'], '/login') ? htmlentities($param['redirect_to']) : Util::url(($this->lang == 'zh-CN' ? '' : "/{$this->lang}") . '/admin/');
        if ($this->checkLogin())
            exit(Util::errMsg(['code' => 0, 'msg' => Util::tran('你已经登录'), 'url' => $jump]));
        if (Util::isAjax()) {
            $ip = Util::getIp();
            $param = Util::param(['username', 'password', 'captcha', 'remember']);
            if (empty($param['username']) || !preg_match('#^[a-z0-9_-]{3,12}$#', $param['username']))
                Util::errMsg(Util::tran('用户名只能英文字母数字下划线或中划线，位数') . ' 3~12');
            if (empty($param['password']) || strlen($param['password']) < 5)
                Util::errMsg(Util::tran('密码至少位数') . ' 5');
            if (empty($param['captcha']) || strtolower($param['captcha']) !== strtolower($_SESSION['captcha']))
                Util::errMsg(Util::tran('验证码不正确'));
            if (!in_array($param['remember'], [0, 1]))
                Util::errMsg(Util::tran('包含非法参数'));

            // 数据库查询
            $user = Model::fetch("SELECT * FROM `user` WHERE `username`=:username AND `password`=:password ORDER BY `id` ASC LIMIT 1", [
                'username' => $param['username'],
                'password' => md5(base64_encode($param['password']))
            ]);
            if (!$user) {
                Util::config('log') && Model::insert('log', ['author' => $param['username'], 'request_method' => 'ajax', 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('管理登录'), 'message' => Util::tran('用户名或密码错误'), 'ip' => $ip, 'status' => 1, 'time' => time()]);
                Util::errMsg(Util::tran('用户名或密码错误'));
            }
            if ('1' == $user['status']) {
                Util::config('log') && Model::insert('log', ['author' => $param['username'], 'request_method' => 'ajax', 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('管理登录'), 'message' => Util::tran('账号被禁用'), 'ip' => $ip, 'status' => 1, 'time' => time()]);
                Util::errMsg(Util::tran('你的账号已被禁用，请联系管理员'));
            }

            // 登录成功
            $_SESSION['uid'] = $user['id'];

            // 记住登录
            $token = md5($user['username'] . md5(base64_encode($user['password'])));
            if ('1' == $param['remember']) {
                setcookie('token', $token, time() + 3600 * 24 * 30, '/');
                Model::update('user', ['remember_token' => $token], ['id' => $user['id']]);
            } else {
                Model::update('user', ['remember_token' => ''], ['id' => $user['id']]);
            }

            // 单点登录
            $setting = Model::fetch('SELECT * FROM `setting` WHERE id=:id ORDER BY `id` ASC LIMIT 1', [':id' => 1]);
            if ($setting && ($check = json_decode($setting['value'], true)) && isset($check['alone_login']) && $check['alone_login']) {
                $randstr = md5($token . rand(100000, 999999));
                Util::setCache('rand' . $user['id'], $randstr);
                setcookie('randstr', $randstr, time() + 3600 * 24 * 30, '/');
            }

            // 更新时间
            !$user['first_login'] && Model::update('user', ['first_login' => time()], ['id' => $user['id']]);
            Model::update('user', ['last_login' => time()], ['id' => $user['id']]);

            // 记录日志
            Util::config('log') && Model::insert('log', ['author' => $user['username'], 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('管理登录'), 'message' => Util::tran('登录成功'), 'ip' => $ip, 'status' => 0, 'time' => time()]);

            // 清除来源页缓存
            $this->clearOrgin();

            // 登录跳转
            exit(Util::errMsg(['code' => 0, 'msg' => Util::tran('登录成功'), 'token' => $token, 'url' => $jump]));
        }
        View::assign('tran', [
            'username' => Util::tran('用户名'),
            'input_username' => Util::tran('请输入用户名'),
            'password' => Util::tran('密码'),
            'input_password' => Util::tran('请输入密码'),
            'verycode' => Util::tran('验证码'),
            'remember_me' => Util::tran('记住我'),
            'login' => Util::tran('登录'),
            'switch_register' => Util::tran('切换注册'),
            'reset' => Util::tran('重置'),
            'info' => Util::tran('信息'),
        ]);
        View::display('admin/account/login.html');
    }

    // 登出
    public function logout()
    {
        $param = Util::param(['redirect_to']);
        $jump = isset($param['redirect_to']) && false === strpos($param['redirect_to'], '/logout') ? htmlentities($param['redirect_to']) : Util::url(($this->lang == 'zh-CN' ? '' : "/{$this->lang}") . '/admin/login.html');
        $row = $this->checkLogin();
        !$row && exit(Util::errMsg(['code' => 0, 'msg' => Util::tran('你已登出'), 'url' => $jump]));

        // 清除token
        Model::update('user', ['remember_token' => ''], ['id' => $row['id']]);
        // 记录日志
        $username = Model::fetchColumn("SELECT `username` FROM `user` WHERE `id`=:id ORDER BY `id` ASC LIMIT 1", ['id' => $row['id']]);
        Util::config('log') && Model::insert('log', ['author' => $username, 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('管理登录'), 'message' => Util::tran('登出成功'), 'ip' => Util::getIp(), 'status' => 0, 'time' => time()]);
        // 清除session和cookie
        unset($_SESSION['uid']);
        setcookie('token', '', time() - 3600, '/');
        setcookie('randstr', '', time() - 3600, '/');
        Util::delCache('rand' . $row['id']);
        // 清除来源页缓存
        $this->clearOrgin();
        exit(Util::errMsg(['code' => 0, 'msg' => Util::tran('登出成功'), 'token' => '', 'url' => $jump]));
    }

    // 注册
    public function register()
    {
        $param = Util::param(['redirect_to']);
        $jump = isset($param['redirect_to']) && false === strpos($param['redirect_to'], '/register') ? htmlentities($param['redirect_to']) : Util::url(($this->lang == 'zh-CN' ? '' : "/{$this->lang}") . '/admin/');
        if ($this->checkLogin())
            exit(Util::errMsg(['code' => 0, 'msg' => Util::tran('你已经登录'), 'url' => $jump]));
        if (Util::isAjax()) {
            $param = Util::param(['username', 'password', 'repeat_password', 'captcha', 'nickname', 'phone', 'remember']);
            if (empty($param['username']) || !preg_match('#^[a-z0-9_-]{3,12}$#', $param['username']))
                Util::errMsg(Util::tran('用户名只能英文字母数字下划线或中划线，位数') . ' 3~12');
            if (empty($param['password']) || strlen($param['password']) < 5)
                Util::errMsg(Util::tran('密码至少位数') . ' 5');
            if ($param['password'] !== $param['repeat_password'])
                Util::errMsg(Util::tran('两次密码输入不一致'));
            if (empty($param['captcha']) || strtolower($param['captcha']) !== strtolower($_SESSION['captcha']))
                Util::errMsg(Util::tran('验证码不正确'));
            if (!empty($param['nickname']) && !preg_match('#^[\x{4e00}-\x{9fa5}A-Za-z0-9_-]{2,12}$#u', $param['nickname']))
                Util::errMsg(Util::tran('昵称只能中英文字母数字下划线中划线，位数') . ' 2~12');
            if (!empty($param['phone']) && !preg_match('#^1((34[0-8]\d{7})|((3[0-3|5-9])|(4[5-7|9])|(5[0-3|5-9])|(66)|(7[2-3|5-8])|(8[0-9])|(9[1|8|9]))\d{8})$#', $param['phone']))
                Util::errMsg(Util::tran('手机号码不正确'));

            $remember_me = $param['remember'];
            $param['password'] = md5(base64_encode($param['password']));
            unset($param['repeat_password']);
            unset($param['captcha']);
            unset($param['remember']);

            // 验证用户名或手机号重复
            $check = Model::fetchColumn("SELECT `username` FROM `user` WHERE `username`=:username ORDER BY `id`", [':username' => $param['username']]);
            $check && Util::errMsg(Util::tran('用户名已存在'));
            if (!empty($param['phone'])) {
                $check = Model::fetchColumn("SELECT `phone` FROM `user` WHERE `phone`=:phone ORDER BY `id`", [':phone' => $param['phone']]);
                $check && Util::errMsg(Util::tran('手机号码已存在'));
            }

            // 写入数据库记录日志
            $param['role_id'] = 2;
            $param['reg_time'] = time();
            $lastInsertId = Model::insert('user', $param);
            if ($lastInsertId) {
                // 注册后登录
                $_SESSION['uid'] = $lastInsertId;

                // 记住登录
                $token = md5($param['username'] . md5(base64_encode($param['password'])));
                if ('1' == $remember_me) {
                    setcookie('token', $token, time() + 3600 * 24 * 30, '/');
                    Model::update('user', ['remember_token' => $token], ['id' => $lastInsertId]);
                } else {
                    Model::update('user', ['remember_token' => ''], ['id' => $lastInsertId]);
                }

                // 单点登录
                $setting = Model::fetch('SELECT * FROM `setting` WHERE id=:id ORDER BY `id` ASC LIMIT 1', [':id' => 1]);
                if ($setting && ($check = json_decode($setting['value'], true)) && isset($check['alone_login']) && $check['alone_login']) {
                    $randstr = md5($token . rand(100000, 999999));
                    Util::setCache('rand' . $lastInsertId, $randstr);
                    setcookie('randstr', $randstr, time() + 3600 * 24 * 30, '/');
                }

                // 更新时间
                $user = Model::fetch('SELECT * FROM `user` WHERE `id`=:id', [':id' => $lastInsertId]);
                !$user['first_login'] && Model::update('user', ['first_login' => time()], ['id' => $user['id']]);
                Model::update('user', ['last_login' => time()], ['id' => $user['id']]);

                // 修改媒体状态
                if (isset($param['avatar']) && preg_match('#/static/upload/.+?\.[png|jpg|jpeg|gif]#', $param['avatar'])) {
                    if (is_file(IA_ROOT . str_replace($this->base_url, '', $param['avatar']))) {
                        Model::update('media', ['status' => 0], ['path' => str_replace($this->base_url, '', $param['avatar'])]);
                    } else {
                        Model::update('media', ['status' => 2], ['path' => str_replace($this->base_url, '', $param['avatar'])]);
                    }
                }

                // 清除来源页缓存
                $this->clearOrgin();
                Util::config('log') && Model::insert('log', ['author' => $param['username'], 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('用户注册'), 'message' => Util::tran('用户注册') . " {$param['username']} " . Util::tran('成功'), 'ip' => Util::getIp(), 'status' => 0, 'time' => time()]);
                Util::errMsg(['code' => 0, 'msg' => Util::tran('注册成功'), 'token' => $token, 'url' => $jump]);
            } else {
                Util::config('log') && Model::insert('log', ['author' => $param['username'], 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('用户注册'), 'message' => Util::tran('用户注册') . " {$param['username']} " . Util::tran('失败'), 'ip' => Util::getIp(), 'status' => 1, 'time' => time()]);
                Util::errMsg(['code' => 1, 'msg' => Util::tran('注册失败')]);
            }
            return;
        }
        View::assign('tran', [
            'username' => Util::tran('用户名'),
            'input_username' => Util::tran('请输入用户名'),
            'password' => Util::tran('密码'),
            'input_password' => Util::tran('请输入密码'),
            'repeat_password' => Util::tran('重复密码'),
            'input_repeat_password' => Util::tran('请重输入密码'),
            'verycode' => Util::tran('验证码'),
            'nickname' => Util::tran('昵称'),
            'optional' => Util::tran('选填'),
            'phone' => Util::tran('手机号'),
            'register' => Util::tran('注册'),
            'switch_login' => Util::tran('切换登录'),
            'remember_me' => Util::tran('记住我'),
            'reset' => Util::tran('重置'),
            'info' => Util::tran('信息'),
        ]);
        View::display('admin/account/register.html');
    }

    // 修改资料
    public function profile()
    {
        $row = $this->checkLogin();
        !$row && Util::errMsg(['msg' => Util::tran('请先登录'), 'url' => Util::url(($this->lang == 'zh-CN' ? '' : "/{$this->lang}") . '/admin/login.html')]);
        if (Util::isAjax()) {
            $param = Util::param(['id', 'username', 'password', 'nickname', 'phone', 'avatar']);
            $user = Model::fetch("SELECT * FROM `user` WHERE `id`=:id", [':id' => $param['id']]);
            (!$user || $param['id'] != $row['id']) && Util::errMsg('ID ' . Util::tran('错误'));
            if (!empty($param['password'])) {
                strlen($param['password']) < 5 && Util::errMsg(Util::tran('密码至少位数') . ' 5');
                $param['username'] == 'anonymous' && Util::errMsg(Util::tran('该用户密码不可修改'));
                $param['password'] = md5(base64_encode($param['password']));
            } else {
                unset($param['password']);
            }
            if (!empty($param['nickname']) && !preg_match('#^[\x{4e00}-\x{9fa5}A-Za-z0-9_-]{2,12}$#u', $param['nickname']))
                Util::errMsg(Util::tran('昵称只能中英文字母数字下划线中划线，位数') . ' 2~12');
            if (!empty($param['phone']) && !preg_match('#^1((34[0-8]\d{7})|((3[0-3|5-9])|(4[5-7|9])|(5[0-3|5-9])|(66)|(7[2-3|5-8])|(8[0-9])|(9[1|8|9]))\d{8})$#', $param['phone']))
                Util::errMsg(Util::tran('手机号码不正确'));
            if (!empty($param['avatar'])) {
                !preg_match('#/static/upload/.+?\.[png|jpg|jpeg|gif]#', $param['avatar']) && Util::errMsg(Util::tran('图片格式错误'));
                $param['avatar'] = str_replace($this->base_url, '', $param['avatar']);
            }

            // 更新数据库记录日志
            $rowCount = Model::update('user', $param, ['id' => $param['id']]);
            // 修改媒体状态
            $paths = [0 => [], 1 => [], 2 => []];
            if (!empty($user['avatar']) && preg_match('#/static/upload/.+?\.[png|jpg|jpeg|gif]#', $user['avatar'])) {
                if (is_file(IA_ROOT . str_replace($this->base_url, '', $user['avatar']))) {
                    $paths[1][] = str_replace($this->base_url, '', $user['avatar']);
                } else {
                    $paths[2][] = str_replace($this->base_url, '', $user['avatar']);
                }
            }
            if (!empty($param['avatar']) && preg_match('#/static/upload/.+?\.[png|jpg|jpeg|gif]#', $param['avatar'])) {
                if (is_file(IA_ROOT . str_replace($this->base_url, '', $param['avatar']))) {
                    $paths[0][] = str_replace($this->base_url, '', $param['avatar']);
                } else {
                    $paths[2][] = str_replace($this->base_url, '', $param['avatar']);
                }
            }
            $paths[1] = array_filter($paths[1], function ($item) use ($paths) {
                return !in_array($item, $paths[0]);
            });
            $paths[1] && Model::update('media', ['status' => 1], ['path' => array_unique($paths[1])]);
            $paths[0] && Model::update('media', ['status' => 0], ['path' => array_unique($paths[0])]);
            $paths[2] && Model::update('media', ['status' => 2], ['path' => array_unique($paths[2])]);
            if ($rowCount) {
                Util::config('log') && Model::insert('log', ['author' => $user['username'], 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('修改资料'), 'message' => Util::tran('修改资料') . " {$user['username']} " . Util::tran('成功'), 'ip' => Util::getIp(), 'status' => 0, 'time' => time()]);
                Util::errMsg(['code' => 0, 'msg' => Util::tran('修改资料成功')]);
            } else {
                Util::config('log') && Model::insert('log', ['author' => $user['username'], 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('修改资料'), 'message' => Util::tran('没有改变') . " {$user['username']} " . Util::tran('信息'), 'ip' => Util::getIp(), 'status' => 0, 'time' => time()]);
                Util::errMsg(['code' => 1, 'msg' => Util::tran('没有改变信息')]);
            }
            return;
        }
        View::assign('row', $row);
        View::assign('tran', [
            'username' => Util::tran('用户名'),
            'input_username' => Util::tran('请输入用户名'),
            'cannot_modify' => Util::tran('不可修改'),
            'password' => Util::tran('密码'),
            'empty_not_change' => Util::tran('留空不修改'),
            'nickname' => Util::tran('昵称'),
            'phone' => Util::tran('手机号'),
            'avatar' => Util::tran('头像'),
            'upload' => Util::tran('上传'),
            'upload_fail' => Util::tran('上传失败'),
            'save' => Util::tran('保存'),
            'reset' => Util::tran('重置'),
            'info' => Util::tran('信息'),
        ]);
        View::display('admin/account/profile.html');
    }

    // 图片验证码
    public function captcha()
    {
        Util::captcha();
    }

    // 清除缓存
    public function clear()
    {
        foreach (glob(IA_ROOT . '/mvc/tpl/*/*.php') as $file)
            unlink($file);
        foreach (glob(IA_ROOT . '/mvc/tpl/*') as $dir)
            rmdir($dir);
        exit(Util::errMsg(['code' => 0, 'msg' => Util::tran('清除成功')]));
    }

    // 清除来源页缓存
    private function clearOrgin()
    {
        if (isset($_SERVER["HTTP_REFERER"])) {
            $file_name = md5($_SERVER["HTTP_REFERER"]);
            if ($pos = strpos($_SERVER["HTTP_REFERER"], 'redirect_to=')) {
                $file_name = md5(substr($_SERVER["HTTP_REFERER"], $pos + 12));
            }
            $cache_file = IA_ROOT . '/mvc/tpl/' . substr($file_name, 0, 2) . '/' . $file_name . '.php';
            is_file($cache_file) && unlink($cache_file);
        }
    }

    // 检查登录
    private function checkLogin()
    {
        $row = false;
        if (!isset($_SESSION['uid']) || empty($_SESSION['uid'])) {
            if (!isset($_COOKIE['token']) || empty($_COOKIE['token'])) return false;
            $row = Model::fetch("SELECT * FROM `user` WHERE `remember_token`=:token ORDER BY `id` ASC LIMIT 1", [':token' => $_COOKIE['token']]);
            if (!$row) return false;
            $_SESSION['uid'] = $row['id'];
        }
        !$row && $row = Model::fetch("SELECT * FROM `user` WHERE `id`=:id ORDER BY `id` ASC LIMIT 1", [':id' => $_SESSION['uid']]);
        if (!$row) return false;

        // 检查单点登录
        $setting = Model::fetch('SELECT * FROM `setting` WHERE id=:id ORDER BY `id` ASC LIMIT 1', [':id' => 1]);
        if ($setting && ($check = json_decode($setting['value'], true)) && isset($check['alone_login']) && $check['alone_login']) {
            $randstr = isset($_COOKIE['randstr']) ? $_COOKIE('randstr') : false;
            $cache_randstr = Util::getCache('rand' . $row['id']);
            if ($randstr !== $cache_randstr) {
                return false;
            }
        }

        return $row;
    }
}
